package com.ljy.my_study.io.NIO.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

/**
 * @author James
 * @date 2018年11月5日
 */
public class Server {
	public static void main(String[] args) throws IOException {
		Selector selector=null;
		try {
			Charset utf8 = Charset.forName("UTF-8");
			SelectorProvider provider = SelectorProvider.provider();
			// ServerSocketChannel ssc=ServerSocketChannel.open();
			ServerSocketChannel ssc = provider.openServerSocketChannel();
			selector = provider.openSelector();
			ssc.configureBlocking(false);
			ssc.bind(new InetSocketAddress(2333));
			ssc.register(selector, SelectionKey.OP_ACCEPT);
			while (true) {
				int readyChannels=selector.select();
				if(readyChannels==0) {
					continue;
				}
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> it = selectionKeys.iterator();
				while (it.hasNext()) {
					SelectionKey key = it.next();
					it.remove();
					if (key.isAcceptable()) {
						ServerSocketChannel server = (ServerSocketChannel) key.channel();
						SocketChannel clientChannel;
						clientChannel = ssc.accept();
						clientChannel.configureBlocking(false);
						SelectionKey selectionKey = clientChannel.register(selector, SelectionKey.OP_READ);
						BufferCarrier bc = new BufferCarrier(256, 256);
						selectionKey.attach(bc);
					}
					if (key.isValid() && key.isReadable()) {
						SocketChannel socketChannel = (SocketChannel) key.channel();
						BufferCarrier c = (BufferCarrier) key.attachment();
						c.getReadBuffer().clear();
						socketChannel.read(c.getReadBuffer());
						c.getReadBuffer().flip();
						System.out.println("接收到：" + String.valueOf(utf8.decode(c.getReadBuffer()).array()));
						c.getReadBuffer().rewind();
						c.getWriteBuffer().put("接收的数据：".getBytes());
						c.getWriteBuffer().put(c.getReadBuffer());
						c.getReadBuffer().clear();
						key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
					}
					if (key.isValid() && key.isWritable()) {
						BufferCarrier c = (BufferCarrier) key.attachment();
						ByteBuffer wb = c.getWriteBuffer();
						wb.flip();
						SocketChannel sc = (SocketChannel) key.channel();
						int len = 0;
						while (wb.hasRemaining()) {
							len = sc.write(wb);
							if (len == 0) {
								break;
							}
						}
						wb.compact();
//						wb.clear();
						if (len != 0)
							key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
					}
				}
				Thread.sleep(500);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(selector!=null) {
				selector.close();
			}
		}
	}
}
